/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import Card from '@/components/card'
import {ArrowLeftOutlined} from '@vicons/antd'
import {NButton, NFormItem, NIcon, NSelect, NSpace, NImage} from 'naive-ui'
import {defineComponent, onMounted, Ref, ref, watch} from 'vue'
import {useI18n} from 'vue-i18n'
import styles from './index.module.scss'
import UseTree from '@/views/projects/workflow/definition/tree/use-tree'
import {IChartDataItem} from '@/components/chart/modules/types'
import {Router, useRouter} from 'vue-router'
import {viewTree} from '@/service/modules/process-definition'
import {SelectMixedOption} from 'naive-ui/lib/select/src/interface'
import {find} from 'lodash'
import {tasksState} from '@/common/common'
import type {ITaskTypeNodeOption} from './types'

export default defineComponent({
    name: 'WorkflowDefinitionTiming',
    setup() {
        const router: Router = useRouter()
        const {t, locale} = useI18n()
        const options: Ref<Array<SelectMixedOption>> = ref([
            {label: '25', value: 25},
            {label: '50', value: 50},
            {label: '75', value: 75},
            {label: '100', value: 100}
        ])

        const projectCode = ref(
            Number(router.currentRoute.value.params.projectCode)
        )
        const definitionCode = ref(
            Number(router.currentRoute.value.params.definitionCode)
        )

        const chartData: Ref<Array<IChartDataItem>> = ref([] as IChartDataItem[])
        const taskStateMap = ref()

        const taskTypeNodeOptions: Ref<Array<ITaskTypeNodeOption>> = ref([
            {
                taskType: 'SHELL',
                color: '#646464',
                image: `${import.meta.env.BASE_URL}images/task-icons/shell.png`
            },
            {
                taskType: 'SUB_PROCESS',
                color: '#4295DA',
                image: `${import.meta.env.BASE_URL}images/task-icons/sub_process.png`
            },
            {
                taskType: 'PROCEDURE',
                color: '#545CC6',
                image: `${import.meta.env.BASE_URL}images/task-icons/procedure.png`
            },
            {
                taskType: 'SQL',
                color: '#8097A0',
                image: `${import.meta.env.BASE_URL}images/task-icons/sql.png`
            },
            {
                taskType: 'SPARK',
                color: '#a16435',
                image: `${import.meta.env.BASE_URL}images/task-icons/spark.png`
            },
            {
                taskType: 'FLINK',
                color: '#d68f5b',
                image: `${import.meta.env.BASE_URL}images/task-icons/flink.png`
            },
            {
                taskType: 'MR',
                color: '#A1A5C9',
                image: `${import.meta.env.BASE_URL}images/task-icons/mr.png`
            },
            {
                taskType: 'PYTHON',
                color: '#60BCD5',
                image: `${import.meta.env.BASE_URL}images/task-icons/python.png`
            },
            {
                taskType: 'DEPENDENT',
                color: '#60BCD5',
                image: `${import.meta.env.BASE_URL}images/task-icons/dependent.png`
            },
            {
                taskType: 'HTTP',
                color: '#7f3903',
                image: `${import.meta.env.BASE_URL}images/task-icons/http.png`
            },
            {
                taskType: 'DATAX',
                color: '#75CC71',
                image: `${import.meta.env.BASE_URL}images/task-icons/datax.png`
            },
            {
                taskType: 'PIGEON',
                color: '#5EC459',
                image: `${import.meta.env.BASE_URL}images/task-icons/pigeon.png`
            },
            {
                taskType: 'SQOOP',
                color: '#f98b3d',
                image: `${import.meta.env.BASE_URL}images/task-icons/sqoop.png`
            },
            {
                taskType: 'CONDITIONS',
                color: '#b99376',
                image: `${import.meta.env.BASE_URL}images/task-icons/conditions.png`
            },
            {
                taskType: 'SWITCH',
                color: '#ff6f00',
                image: `${import.meta.env.BASE_URL}images/task-icons/switch.png`
            },
            {
                taskType: 'SEATUNNEL',
                color: '#8c8c8f',
                image: `${import.meta.env.BASE_URL}images/task-icons/seatunnel.png`
            },
            {
                taskType: 'DINKY',
                color: '#d69f5b',
                image: `${import.meta.env.BASE_URL}images/task-icons/dinky.png`
            },
            {taskType: 'DAG', color: '#bbdde9'},
            {
                taskType: 'FLINK_STREAM',
                color: '#d68f5b',
                image: `${import.meta.env.BASE_URL}images/task-icons/flink.png`
            }
        ])

        const initTaskStateMap = () => {
            taskStateMap.value = Object.entries(tasksState(t)).map(([key, item]) => ({
                state: key,
                value: item.desc,
                color: item.color
            }))
        }

        const initChartData = (node: any, newNode: any) => {
            newNode.children = []
            node?.children.map((child: any) => {
                const newChild = {}
                initChartData(child, newChild)
                newNode.children.push(newChild)
            })

            newNode.name = node.name
            newNode.value = node.name === 'DAG' ? 'DAG' : node?.type
            const taskTypeNodeOption = find(taskTypeNodeOptions.value, {
                taskType: newNode.value
            })
            if (taskTypeNodeOption) {
                newNode.itemStyle = {color: taskTypeNodeOption.color}
                if (newNode.name !== 'DAG') {
                    let taskState = null
                    if (
                        node.instances &&
                        node.instances.length > 0 &&
                        node.instances[0].state
                    ) {
                        taskState = find(taskStateMap.value, {
                            state: node.instances[0].state
                        })
                    }
                    newNode.label = {
                        show: true,
                        formatter: [
                            `{name|${t('project.task.task_name')}:${newNode.name}}`,
                            `{type|${t('project.task.task_type')}:${
                                taskTypeNodeOption.taskType
                            }}`,
                            taskState
                                ? `{state|${t('project.workflow.task_state')}: ${
                                    taskState.value
                                }}`
                                : ''
                        ].join('\n'),
                        rich: {
                            type: {
                                lineHeight: 20,
                                align: 'left'
                            },
                            name: {
                                lineHeight: 20,
                                align: 'left'
                            },
                            state: {
                                lineHeight: 20,
                                align: 'left',
                                color: taskState ? taskState.color : 'black'
                            }
                        }
                    }
                }
            }
        }

        const getWorkflowTreeData = async (limit: number) => {
            if (projectCode.value && definitionCode) {
                const res = await viewTree(projectCode.value, definitionCode.value, {
                    limit: limit
                })
                chartData.value = [{name: 'DAG', value: 'DAG'}]
                initChartData(res, chartData.value[0])
            }
        }

        const onSelectChange = (value: number) => {
            if (value) {
                getWorkflowTreeData(value)
            }
        }

        const initData = () => {
            initTaskStateMap()
            getWorkflowTreeData(25)
        }

        onMounted(() => {
            initData()
        })

        watch(
            () => locale.value,
            () => {
                initData()
            }
        )

        return {
            chartData,
            options,
            onSelectChange,
            taskTypeNodeOptions
        }
    },
    render() {
        const {chartData, options, onSelectChange, taskTypeNodeOptions} = this
        const {t} = useI18n()
        const router: Router = useRouter()

        return (
            <div class={styles.content}>
                <Card class={styles.card}>
                    <div class={styles.header}>
                        <NButton type='primary' onClick={() => router.go(-1)}>
                            <NIcon>
                                <ArrowLeftOutlined/>
                            </NIcon>
                        </NButton>
                        <NFormItem
                            size={'small'}
                            class={styles.right}
                            showFeedback={false}
                            labelPlacement={'left'}
                            label={t('project.workflow.tree_limit')}
                        >
                            <NSelect
                                size='small'
                                defaultValue={25}
                                onUpdateValue={onSelectChange}
                                options={options}
                            />
                        </NFormItem>
                    </div>
                </Card>
                <Card title={t('project.workflow.tree_view')}>
                    <NSpace align='center'>
                        {taskTypeNodeOptions
                            .filter((option: any) => option.image)
                            .map((option: any, unused: number) => (
                                <NButton text size='tiny' color={option.color}>
                                    <NImage width='20' src={option.image}/>
                                    {option.taskType}
                                </NButton>
                            ))}
                    </NSpace>
                    <UseTree chartData={chartData}/>
                </Card>
            </div>
        )
    }
})
